/*
* @author: Brandon Wong
*/
package com.apps.services;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import com.apps.datastore.dao.CourseInformationObject;
import com.apps.datastore.dao.SectionInformationObject;
import com.apps.ubc.cc.model.BuildingModel;
import com.apps.ubc.cc.model.GoogleDirectionModel;
import com.apps.ubc.cc.model.LatLongModel;
public class CourseSummaryService {
private final static String[] days = { "Mon", "Tue", "Wed", "Thu", "Fri" };
private final static String[] term = { "1", "2" };
/*
* Prints out the summary schedule of the terms and days.
*/
public String getSummarySchedule(List<SectionInformationObject> course) {
String summary = "";
List<SectionInformationObject> sort_term;
for (int j = 0; j < term.length; j++) {
summary = summary.concat("Term " + term[j] + ":\n");
sort_term = sortTerm(course, term[j]);
for (int i = 0; i < days.length; i++) {
summary = summary.concat(sortDayBreak(sort_term, days[i]));
}
summary = summary.concat("\n");
}
sort_term = null;
return summary;
}
public List<LatLongModel> findUnique(
List<LatLongModel> list) {
List<LatLongModel> result = new ArrayList<LatLongModel>();
for(Iterator<LatLongModel> i = list.iterator(); i.hasNext();){
LatLongModel llm = i.next();
if(!result.contains(llm))
result.add(llm);
}
return result;
}
// Takes in a unsorted list of SIO and returns the lat/long of the SIO
// specified by term. Sorted by day and then by time.
public List<LatLongModel> getLatLongByTerm(
List<SectionInformationObject> course_list, String term) {
if (course_list == null || term == null) {
return null;
} else if (course_list.size() == 0) {
return null;
} else if (!(term.equals("1") || term.equals("2"))) {
return null;
}
// list to store sorted term
List<SectionInformationObject> sorted_term = new LinkedList<SectionInformationObject>();
// List to store sorted Day
List<SectionInformationObject> sorted_day = null;
// Return type
List<LatLongModel> latLong = new LinkedList<LatLongModel>();
List<LatLongModel> buffer;
for (int i = 0; i < course_list.size(); i++) {
// Sort by term.
if (course_list.get(i).getTerm().equals(term)) {
sorted_term.add(course_list.get(i));
}
}
// Now it's sorted by term. Remove duplicate
// sorted_term=findUnique(sorted_term);
for (int j = 0; j < days.length; j++) {
// Now, sort by day.
sorted_day = sortByDay(sorted_term, days[j]);
// Lastly, sort by time
sorted_day = sort(sorted_day);
buffer = getLatLongInDay(sorted_day);
if (buffer.size() != 0) {
latLong.addAll(buffer);
}
}
List<LatLongModel> llml = findUnique(latLong);
// Now it's sorted by term and time.
return llml;
}
// Gets the lat/long of a sorted List of a day.
private List<LatLongModel> getLatLongInDay(
List<SectionInformationObject> course_list) {
List<LatLongModel> sort_term = new LinkedList<LatLongModel>();
if (course_list.size() == 0) {
return sort_term;
}
for (int j = 0; j < course_list.size(); j++) {
// This is to get the lat/long
UBCWayfindingService addrParser;
BuildingModel addr;
addrParser = new UBCWayfindingService();
addr = addrParser.search(course_list.get(j).getBuilding());
if (addr != null) {
LatLongModel geo = new LatLongModel(addr.getLatitude(),
addr.getLongitude());
sort_term.add(geo);
System.out.println("Course name: "
+ course_list.get(j).getSectionId());
}
}
return sort_term;
}
/*
* Finds the break within classes in a day.
*/
private String findBreakinDay(List<SectionInformationObject> day,
String today) {
double total_distance = 0;
int total_time = 0;
// First sort it...
day = sort(day);
String breaktime = today + ":\n";
GoogleDirectionsService service = new GoogleDirectionsService();
// Now we form the summary statement.
if (day.size() == 0) {
breaktime = breaktime.concat("No class.\n");
} else if (day.size() == 1) {
breaktime = breaktime.concat("There's only one lesson today.\n");
}
for (int i = 0; i < day.size() - 1; i++) {
if (i == 0) {
breaktime = breaktime.concat("Your lecture starts at "
+ day.get(i).getStart() + "\n");
}
SectionInformationObject class_1 = day.get(i);
SectionInformationObject class_2 = day.get(i + 1);
GoogleDirectionModel model = service
.getDirections(class_1, class_2);
total_distance += model.getDistance();
total_time += model.getTime();
if (!class_1.getEnd().equals(class_2.getStart())) {
breaktime = breaktime.concat("Break from: ");
breaktime = breaktime.concat(class_1.getEnd());
breaktime = breaktime.concat("-");
breaktime = breaktime.concat(class_2.getStart());
breaktime = breaktime.concat("\n");
}
if (i == day.size() - 1) {
breaktime = breaktime.concat("Your lecture ends at "
+ day.get(i).getStart() + "\n");
}
}
// Now that the summary of classes are printed. Print the total
// walking time.
breaktime = breaktime.concat("Total walking distance is "
+ total_distance + "m\n");
breaktime = breaktime.concat("Total time is " + total_time + "m\n");
return breaktime;
}
/*
* Sort the given list by it's start time
*/
public List<SectionInformationObject> sort(
List<SectionInformationObject> to_sort) {
List<SectionInformationObject> sorted = new LinkedList<SectionInformationObject>();
boolean changed;
for (int i = 0; i < to_sort.size(); i++) {
changed = false;
for (int j = 0; j < sorted.size(); j++) {
// Parse the time first.
String[] time_1 = to_sort.get(i).getStart().split(":");
String[] time_2 = sorted.get(j).getStart().split(":");
int hour_1 = Integer.parseInt(time_1[0]);
int hour_2 = Integer.parseInt(time_2[0]);
if (hour_1 < hour_2) {
if (j == 0) {
// The first element
sorted.add(0, to_sort.get(i));
changed = true;
} else {
sorted.add(j, to_sort.get(i));
changed = true;
}
break;
} else if (hour_1 == hour_2) {
int min_1 = Integer.parseInt(time_1[1]);
int min_2 = Integer.parseInt(time_2[1]);
if (min_1 > min_2) {
if (j == 0) {
// THe first element
sorted.add(0, to_sort.get(i));
changed = true;
} else {
sorted.add(j, to_sort.get(i));
changed = true;
}
}
break;
}
}
if (changed == false) {
sorted.add(to_sort.get(i));
}
}
return sorted;
}
/*
* Returns a list with the same term
*/
private List<SectionInformationObject> sortTerm(
List<SectionInformationObject> course, String term) {
if (course == null) {
return null;
}
List<SectionInformationObject> day = new LinkedList<SectionInformationObject>();
for (int i = 0; i < course.size(); i++) {
SectionInformationObject section = course.get(i);
if (section.getTerm().equals(term)) {
day.add(section);
}
}
return day;
}
/*
*
*/
private List<SectionInformationObject> sortByDay(
List<SectionInformationObject> course, String today) {
if (course == null) {
return null;
}
List<SectionInformationObject> day = new LinkedList<SectionInformationObject>();
for (int i = 0; i < course.size(); i++) {
SectionInformationObject section = course.get(i);
String days = section.getDay();
String[] daysing = days.split(" ");
for (int j = 0; j < daysing.length; j++) {
if (today.equals(daysing[j])) {
day.add(section);
}
}
}
return day;
}
/*
* sorts for the same day.
*/
private String sortDayBreak(List<SectionInformationObject> course,
String today) {
if (course == null) {
return null;
}
List<SectionInformationObject> day = new LinkedList<SectionInformationObject>();
for (int i = 0; i < course.size(); i++) {
SectionInformationObject section = course.get(i);
String days = section.getDay();
String[] daysing = days.split(" ");
for (int j = 0; j < daysing.length; j++) {
if (today.equals(daysing[j])) {
day.add(section);
}
}
}
return findBreakinDay(day, today);
}
public String[] getStartEnd(List<SectionInformationObject> day) {
String[] startEnd = new String[2];
startEnd[0] = "8";
startEnd[1] = "17";
if (!day.isEmpty()) {
SectionInformationObject start = findMin(day);
if (start != null && start.getStart().contains(":"))
startEnd[0] = start.getStart().split(":")[0];
SectionInformationObject end = findMax(day);
if (end != null && end.getEnd().contains(":"))
startEnd[1] = end.getEnd().split(":")[0];
}
return startEnd;
}
public SectionInformationObject findMin(
List<SectionInformationObject> courses) {
SectionInformationObject min;
if (courses == null || courses.size() == 0) {
return null;
} else if (courses.size() == 1) {
return courses.get(0);
} else {
min = courses.get(0);
for (int i = 1; i < courses.size(); i++) {
// Parse the courses' time, only needs to check the first
// because the start is always lesser than the end.
String[] t_start = courses.get(i).getStart().split(":");
int t_start_hour = Integer.parseInt(t_start[0]);
int t_start_min = Integer.parseInt(t_start[1]);
// Parse the min's time
String[] m_start = min.getStart().split(":");
int m_start_hour = Integer.parseInt(m_start[0]);
int m_start_min = Integer.parseInt(m_start[1]);
// Now compare the hours, if == then compare the min
if (t_start_hour < m_start_hour) {
min = courses.get(i);
} else if (t_start_hour == m_start_hour) {
// Check if the mins are the same
if (t_start_min < m_start_min) {
min = courses.get(i);
}
}
}
}
return min;
}
// Exactly the same as the findMin but the sign are changed.
// Instead of getting Start, we get End
public SectionInformationObject findMax(
List<SectionInformationObject> courses) {
SectionInformationObject max;
if (courses == null || courses.size() == 0) {
return null;
} else if (courses.size() == 1) {
return courses.get(0);
} else {
max = courses.get(0);
for (int i = 1; i < courses.size(); i++) {
// Parse the courses' time, only needs to check the first
// because the start is always lesser than the end.
String[] t_start = courses.get(i).getEnd().split(":");
int t_start_hour = Integer.parseInt(t_start[0]);
int t_start_min = Integer.parseInt(t_start[1]);
// Parse the min's time
String[] m_start = max.getEnd().split(":");
int m_start_hour = Integer.parseInt(m_start[0]);
int m_start_min = Integer.parseInt(m_start[1]);
// Now compare the hours, if == then compare the min
if (t_start_hour > m_start_hour) {
max = courses.get(i);
} else if (t_start_hour == m_start_hour) {
// Check if the mins are the same
if (t_start_min > m_start_min) {
max = courses.get(i);
}
}
}
}
return max;
}
}